package view;

import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import swingComponents.MyCellEditor;
import swingComponents.MyTableCellRenderer;
import utils.DateUtil;
import utils.JsonUtils;
import utils.StringUtils;

public class QueryView extends BaseView {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private JPanel panel;
	private JTextField from_date_year;
	private JTextField from_date_month;
	private JTextField from_date_day;
	private JTextField from_station;
	private JTextField to_station;
	private JButton queryButton;
	// 用来显示JTable
	private JScrollPane scroll;
	private JTable table;

	// 默认值设置
	private String default_from_date_year;
	private String default_from_date_month;
	private String default_from_date_day;
	private String default_from_station = "杭州";
	private String default_to_station = "厦门";
	private String isAdult = "ADULT";

	//
	private String[] secretStrs;
	private JButton button;

	public QueryView() throws Exception {

	}

	public void init() {
		initComponents();
	}

	private void initComponents() {
		panel = new JPanel();
		JLabel from_date_label = new JLabel("出发日期");
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		default_from_date_year = String.valueOf(calendar.get(Calendar.YEAR));
		default_from_date_month = DateUtil.fillTheDate(calendar
				.get(Calendar.MONTH) + 1);
		default_from_date_day = DateUtil.fillTheDate(calendar
				.get(Calendar.DAY_OF_MONTH));
		from_date_year = new JTextField(String.valueOf(default_from_date_year));
		from_date_month = new JTextField(String
				.valueOf(default_from_date_month));
		from_date_day = new JTextField(String.valueOf(default_from_date_day));

		JLabel from_station_label = new JLabel("出发站");
		from_station = new JTextField(default_from_station);
		JLabel to_station_label = new JLabel("到达站");
		to_station = new JTextField(default_to_station);

		queryButton = new JButton("查询");
		queryButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				try {
					query();
				} catch (UnsupportedEncodingException e1) {
					e1.printStackTrace();
				} catch (FileNotFoundException e2) {
					e2.printStackTrace();
				}
			}
		});

		panel.add(from_date_label);
		panel.add(from_date_year);
		panel.add(from_date_month);
		panel.add(from_date_day);

		panel.add(from_station_label);
		panel.add(from_station);
		panel.add(to_station_label);
		panel.add(to_station);

		panel.add(queryButton);

		this.button = new JButton("刷新");
		this.button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				do_button_actionPerformed(e);
			}
		});
		this.panel.add(this.button);
		table = new JTable();
		scroll = new JScrollPane(table);
		scroll.setPreferredSize(new Dimension(900, 500));
		panel.add(scroll);
		getContentPane().add(panel);

		setSize(950, 600);
		setVisible(true);
		setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
		setLocationRelativeTo(null);
	}

	private void query() throws UnsupportedEncodingException,
			FileNotFoundException {
		// 查询车票
		String from_station_code = getStationCodeFromName(from_station
				.getText());
		String to_station_code = getStationCodeFromName(to_station.getText());
		if (from_station_code == null || to_station_code == null) {
			JOptionPane.showMessageDialog(this, "地区输入有误，请重新输入");
			return;
		}
		String resInfo = controller.queryLeftTickets(DateUtil.formStaDate(
				from_date_year.getText(), from_date_month.getText(),
				from_date_day.getText()), from_station_code, to_station_code,
				isAdult);
		System.out.println(resInfo);
		JSONObject jsonObject = JSONObject.fromObject(resInfo);
		// TODO 是否可以做一个通用的方法？staus貌似只能判断是否登录
		Map<?, ?> map = JsonUtils.getDataMap(resInfo);
		if (StringUtils.isNotBlank(map.get("messages").toString())) {
			JOptionPane.showMessageDialog(this, map.get("messages").toString());
			return;
		}
		JSONArray jsonArray = jsonObject.getJSONArray("data");
		int jsonLen = jsonArray.size();
		// 保存secretStr字符数组
		secretStrs = new String[jsonLen];
		// 构造表格
		String[] headers = { "车次", "出发", "到达", "出发时间", "到达时间", "历时", "商务座",
				"特等座", "一等座", "二等座", "高级软卧", "软卧", "硬卧", "软座", "硬座", "无座",
				"其他", "预定" };
		String[] keys = { "station_train_code", "from_station_name",
				"to_station_name", "start_time", "arrive_time", "lishi",
				"swz_num", "tz_num", "zy_num", "ze_num", "gr_num", "rw_num",
				"yw_num", "rz_num", "yz_num", "wz_num", "qt_num", "" };
		// 掠过预定(还是要加上按钮)
		final int headers_length = headers.length;
		Object[][] cellData = new Object[jsonLen][headers_length];
		for (int j = 0; j < jsonLen; j++) {
			final int trainNum = j;
			final JSONObject train = jsonArray.getJSONObject(j).getJSONObject(
					"queryLeftNewDTO");
			System.out.println(train);
			secretStrs[j] = jsonArray.getJSONObject(j).getString("secretStr");
			secretStrs[j] = URLDecoder.decode(secretStrs[j], "UTF-8");
			for (int i = 0; i < headers_length - 1; i++) {
				cellData[j][i] = train.getString(keys[i]);
			}
			// cellData[j][headers_length - 1] = "预定";
			JButton jButton = new JButton("预定");
			jButton.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					try {
						reserve(trainNum, train);
					} catch (Exception e1) {
						e1.printStackTrace();
					}
				}
			});
			if (train.getString("canWebBuy").equals("N")) {
				jButton.setEnabled(false);
			}
			cellData[j][headers_length - 1] = jButton;
		}
		// 渲染JTable按钮
		DefaultTableModel model = new DefaultTableModel(cellData, headers) {
			public boolean isCellEditable(int row, int column) {
				if(column == headers_length - 1){
					return true;
				}
				return false;
			}

			@Override
			public Class<?> getColumnClass(int columnIndex) {
				Vector vector = (Vector) dataVector.get(0);
				return vector.get(columnIndex).getClass();
			}
		};
		table = new JTable(model);
		scroll.setViewportView(table);
		// 设置列宽
		int indexOfZw = 6;
		for (int i = indexOfZw; i < headers_length - 1; i++) {
			table.getColumnModel().getColumn(i).setPreferredWidth(45);
		}
		table.getColumnModel().getColumn(headers_length - 1).setPreferredWidth(
				100);
		// 设置列高
		table.setRowHeight(25);
		table.setDefaultRenderer(JButton.class, new MyTableCellRenderer());
		table.setDefaultEditor(JButton.class, new MyCellEditor());
		table.setPreferredScrollableViewportSize(new Dimension(200, 70));
//		// 添加事件提交预定
//		table.addMouseListener(new MouseAdapter() {
//			@Override
//			public void mouseClicked(MouseEvent e) {
//				try {
//					reserve(e);
//				} catch (Exception e1) {
//					e1.printStackTrace();
//				}
//			}
//		});
		scroll.updateUI();
	}

	@Deprecated
	/**
	 * 事件写到jButton上面了
	 */
	private void reserve(MouseEvent e) throws Exception {
		Point point = e.getPoint();
		int x = (int) point.getX();
		int y = (int) point.getY();
		if (x > 812 && x < 897) {
			// 提交预定请求
			int trainNum = y / 25;
			// 请求参数
			String secretStr = secretStrs[trainNum];
			// TODO 这里可以增加一个是否非法输入的异常
			String date = DateUtil.formStaDate(from_date_year.getText(),
					DateUtil.fillTheDate(Integer.parseInt(from_date_month
							.getText())), DateUtil.fillTheDate(Integer
							.parseInt(from_date_day.getText())));
			List<NameValuePair> nvps = new ArrayList<NameValuePair>();
			nvps.add(new BasicNameValuePair("secretStr", secretStr));
			nvps.add(new BasicNameValuePair("train_date", date));
			nvps.add(new BasicNameValuePair("back_train_date", date)); // TODO
			// 默认单程
			nvps.add(new BasicNameValuePair("tour_flag", "dc"));// TODO
			nvps.add(new BasicNameValuePair("purpose_codes", isAdult));
			// 这2个参数在这里其实没有用到，只需要secretStr就可以来确定
			nvps.add(new BasicNameValuePair("query_from_station_name", "杭州东"));
			nvps.add(new BasicNameValuePair("query_to_station_name", "厦门"));
			nvps.add(new BasicNameValuePair("undefined", ""));// TODO
			String resInfo = controller.submitOrderRequest(
					"https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest",
					nvps);
			JSONObject jsonObject = JSONObject.fromObject(resInfo);
			if (jsonObject.getBoolean("status")) {
				this.dispose();
//				ReserveView reserveView = new ReserveView();
//				reserveView.setVisible(true);
			} else {
				JOptionPane.showMessageDialog(this, jsonObject
						.getString("messages"));
			}
		}
	}
	
	private void reserve(int trainNum, JSONObject train) throws Exception{
		// 请求参数
		String secretStr = secretStrs[trainNum];
		// TODO 这里可以增加一个是否非法输入的异常
		String date = DateUtil.formStaDate(from_date_year.getText(),
				DateUtil.fillTheDate(Integer.parseInt(from_date_month
						.getText())), DateUtil.fillTheDate(Integer
						.parseInt(from_date_day.getText())));
		List<NameValuePair> nvps = new ArrayList<NameValuePair>();
		nvps.add(new BasicNameValuePair("secretStr", secretStr));
		nvps.add(new BasicNameValuePair("train_date", date));
		nvps.add(new BasicNameValuePair("back_train_date", date)); // TODO
		// 默认单程
		nvps.add(new BasicNameValuePair("tour_flag", "dc"));// TODO
		nvps.add(new BasicNameValuePair("purpose_codes", isAdult));
		// 这2个参数在这里其实没有用到，只需要secretStr就可以来确定
		nvps.add(new BasicNameValuePair("query_from_station_name", "杭州东"));
		nvps.add(new BasicNameValuePair("query_to_station_name", "厦门"));
		nvps.add(new BasicNameValuePair("undefined", ""));// TODO
		String resInfo = controller.submitOrderRequest(
				"https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest",
				nvps);
		JSONObject jsonObject = JSONObject.fromObject(resInfo);
		if (jsonObject.getBoolean("status")) {
			this.dispose();
			ReserveView reserveView = new ReserveView(train);
			reserveView.setVisible(true);
		} else {
			JOptionPane.showMessageDialog(this, jsonObject
					.getString("messages"));
		}	
	}
	
	private String getStationCodeFromName(String name)
			throws UnsupportedEncodingException, FileNotFoundException {
		BufferedReader br = new BufferedReader(new InputStreamReader(
				new FileInputStream("file/station_name.js"), "utf-8"));
		try {
			String stationName = br.readLine();
			stationName = stationName.substring(stationName.indexOf("'") + 2,
					stationName.lastIndexOf("'"));
			String[] stations = stationName.split("@");
			String[] infos = null;
			for (String string : stations) {
				infos = string.split("\\|");
				if (infos[1].equals(name)) {
					return infos[2];
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				br.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	protected void do_button_actionPerformed(ActionEvent e) {
		remove();
		init();
	}

	public void remove() {
		remove(panel);
	}
}
